package com.personal.service.Impl;

import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.personal.bo.AddResourcesBO;
import com.personal.bo.CommentListBO;
import com.personal.bo.NewResourcesBO;
import com.personal.bo.NewResourcesByCatBO;
import com.personal.constant.CommentLevel;
import com.personal.enums.ResourcesEnum;
import com.personal.exception.ExceptionUtils;
import com.personal.mapper.ResourcesImgMapper;
import com.personal.mapper.ResourcesMapper;
import com.personal.mapper.ResourcesSpecMapper;
import com.personal.mapper.UsersMapper;
import com.personal.po.ResourcesPO;
import com.personal.po.ResourcesViewPO;
import com.personal.pojo.PageBean;
import com.personal.pojo.Resources;
import com.personal.pojo.ResourcesImg;
import com.personal.pojo.ResourcesSpec;
import com.personal.service.ResourcesService;
import com.personal.utils.MinIoUtils;
import com.personal.utils.PageUtils;
import com.personal.utils.RedisUtils;
import com.personal.utils.Result;
import com.personal.utils.config.MinIoClientConfig;
import com.personal.vo.CommentListVO;
import com.personal.vo.ResourcesVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class ResourcesServiceImpl implements ResourcesService {

    @Resource
    private ResourcesMapper resourcesMapper;

    @Resource
    private UsersMapper usersMapper;

    @Autowired
    private ResourcesSpecMapper resourcesSpecMapper;

    @Autowired
    private MinIoClientConfig minIoClientConfig;

    @Autowired
    private ResourcesImgMapper resourcesImgMapper;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 分页查询最新的资源文章消息
     * @param newResourcesBO
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Result queryNewResources(NewResourcesBO newResourcesBO) {
        log.info("分页查询最新的资源文章列表接口");

        List<ResourcesVO> resourcesVOList = new ArrayList<>();

        if (newResourcesBO.getPageNum() == 1) {
            String jsonList = (String) redisUtils.get("resourcesVOList");
            if (!StrUtil.isBlank(jsonList)) {
                resourcesVOList = JSONObject.parseArray(jsonList,ResourcesVO.class);
                System.out.println(jsonList);
                return Result.success(resourcesVOList);
            }
        }

        PageHelper.startPage(newResourcesBO.getPageNum(), newResourcesBO.getPageSize());
        List<ResourcesPO> resourcesPOList = resourcesMapper.queryNewResources();
        for (ResourcesPO resourcesPO : resourcesPOList) {
            ResourcesVO resourcesVO = new ResourcesVO();
            BeanUtils.copyProperties(resourcesPO,resourcesVO);

            //根据id查询发布人头像
            String face = usersMapper.getFaceById(resourcesPO.getUserId());
            resourcesVO.setFace(face);

            //根据资源id查询资源图片列表
            List<ResourcesImg> resourcesImgList = resourcesMapper.queryResourcesImg(resourcesPO.getId());
            resourcesVO.setResourcesImgList(resourcesImgList);

            //获取redis中缓存的浏览量
            String key = "resourcesId_" + resourcesVO.getId();
            Long view = redisUtils.size(key);
            if (view != 0){
                Long views = resourcesVO.getViewCount() + view;
                resourcesVO.setViewCount(views);
            }

            //根据分类id查询分类名称
            String catName = resourcesMapper.getResourcesCatName(resourcesPO.getCatId());
            resourcesVO.setCatName(catName);

            resourcesVOList.add(resourcesVO);
        }

        //将list解析成string
        String list = JSONObject.toJSON(resourcesVOList).toString();
        redisUtils.set("resourcesVOList",list);

        return Result.success(PageUtils.restPage(resourcesPOList,resourcesVOList));
    }

    /**
     * 查询资源文章详情接口
     * @param id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Result queryResourcesById(Integer id) {
        log.info("查询资源文章详情接口");
        //判断id是否合法
        if (id == null || id <= 0){
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ID_IS_ERROR);
        }
        ResourcesVO resources = resourcesMapper.queryResourcesById(id);
        if (resources == null){
            ExceptionUtils.error(ResourcesEnum.RESOURCES_DETAILS_ERROR);
        }

        //根据用户id查询用户头像
        String face = usersMapper.getFaceById(resources.getUserId());
        resources.setFace(face);

        //获取redis中缓存的浏览量
        String key = "resourcesId_" + resources.getId();
        Long view = redisUtils.size(key);
        if (view != 0){
            Long views = resources.getViewCount() + view;
            resources.setViewCount(views);
        }

        //根据资源id查询资源图片列表
        List<ResourcesImg> resourcesImgList = resourcesMapper.queryResourcesImg(resources.getId());
        resources.setResourcesImgList(resourcesImgList);

        //根据分类id查询分类名称
        String catName = resourcesMapper.getResourcesCatName(resources.getCatId());
        resources.setCatName(catName);

        return Result.success(resources);
    }

    /**
     * 根据资源id查询资源评价等级数量
     * @param id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Result queryCommonLevelCount(Integer id) {
        log.info("根据资源id查询资源评价等级数量接口");
        if (id == null || id <= 0){
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ID_IS_ERROR);
        }

        HashMap<String, Integer> map = new HashMap<>();

        Integer goodCount = queryCommonLevelCountBy(id, CommentLevel.GOOD_REVIEW);
        Integer middleCount = queryCommonLevelCountBy(id, CommentLevel.MIDDLE_REVIEW);
        Integer negativeCount = queryCommonLevelCountBy(id, CommentLevel.NEGATIVE_REVIEW);
        map.put("goodCount", goodCount);
        map.put("middleCount", middleCount);
        map.put("negativeCount", negativeCount);

        return Result.success(map);
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    /**
     * 通过id和评价等级查询 数量
     */
    public int queryCommonLevelCountBy(int id, int level){
        return resourcesMapper.queryCommonLevelCountBy(id, level);
    }


    /**
     * 分页查询资源文章列表
     * @param commentListBO
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Result queryResourcesCommentList(CommentListBO commentListBO) {
        //判断资源id的合法性
        if (commentListBO.getId() == null || commentListBO.getId() <= 0){
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ID_IS_ERROR);
        }

        PageHelper.startPage(commentListBO.getPageNum(), commentListBO.getPageSize());
        List<CommentListVO> commentListVOList = resourcesMapper.queryResourcesCommentList(commentListBO);
//        PageInfo<CommentListVO> info = new PageInfo<>(commentListVOList);
        for (CommentListVO commentListVO : commentListVOList) {
            commentListVO.setNickname(DesensitizedUtil.chineseName(commentListVO.getNickname()));
        }

        PageBean<CommentListVO> info = new PageBean<>(commentListVOList);

        return Result.success(info);
    }

    /**
     * 获取所有的资源文章id
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Long> getAllResourcesId() {
        return resourcesMapper.getAllResourcesId();
    }

    /**
     * 通过资源id查询资源浏览量
     * @param resourcesId
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public ResourcesViewPO getById(Long resourcesId) {
        return resourcesMapper.getById(resourcesId);
    }

    /**
     * 更新资源浏览量
     * @param resourcesViewPo
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int updateResourcesView(ResourcesViewPO resourcesViewPo) {
        return resourcesMapper.updateResourcesView(resourcesViewPo);
    }

    /**
     * 通过参数查询最新的资源文章
     * @param newResourcesByCatBO
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Result queryNewResourcesByCatAndLimit(NewResourcesByCatBO newResourcesByCatBO) {
        log.info("参数查询最新的资源文章列表接口");
        List<ResourcesVO> resourcesVOList = new ArrayList<>();
        List<ResourcesPO> resourcesPOList = resourcesMapper.queryNewResourcesByCatAndLimit(newResourcesByCatBO);
        for (ResourcesPO resourcesPO : resourcesPOList) {
            ResourcesVO resourcesVO = new ResourcesVO();
            BeanUtils.copyProperties(resourcesPO,resourcesVO);

            //通过用户id查询用户头像
            String face = usersMapper.getFaceById(resourcesPO.getUserId());
            resourcesVO.setFace(face);

            //获取redis中缓存的浏览量
            String key = "resourcesId_" + resourcesVO.getId();
            Long view = redisUtils.size(key);
            if (view != 0){
                Long views = resourcesVO.getViewCount() + view;
                resourcesVO.setViewCount(views);
            }

            //根据资源id查询资源图片列表
            List<ResourcesImg> resourcesImgList = resourcesMapper.queryResourcesImg(resourcesPO.getId());
            resourcesVO.setResourcesImgList(resourcesImgList);

            //通过分类id查询分类名称
            String catName = resourcesMapper.getResourcesCatName(resourcesPO.getCatId());
            resourcesVO.setCatName(catName);

            resourcesVOList.add(resourcesVO);
        }

        return Result.success(resourcesVOList);
    }

    /**
     * 根据id获取资源
     * @param resourcesId
     * @return
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Resources getResourcesById(Integer resourcesId) {
        if (resourcesId == null || resourcesId <= 0) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ID_IS_ERROR);
        }
        Resources resources = resourcesMapper.getResourcesById(resourcesId);
        if (resources == null) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_GET_IS_NULL);
        }
        return resources;
    }

    /**
     * 添加资源文章
     * @param addResourcesBO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public Result addResources(MultipartFile[] resourcesImgs,AddResourcesBO addResourcesBO) throws Exception {
        if(addResourcesBO.getCatId() == null || addResourcesBO.getContent() == null ||
        addResourcesBO.getName() == null || addResourcesBO.getPriceNormal() == null||
        addResourcesBO.getPriceVip() == null|| addResourcesBO.getUrl() == null||
        addResourcesBO.getUserId() == null) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_PARAM_ERROR);
        }
        if (resourcesImgs == null || resourcesImgs.length == 0) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_PARAM_ERROR);
        }
        Resources resources = new Resources();
        BeanUtils.copyProperties(addResourcesBO,resources);
        resources.setSellCount(0);
        resources.setOnOffStatus(1);
        resources.setViewCount(0);
        resources.setValidityPeriod("永久");
        Integer flag = resourcesMapper.addResources(resources);
        if (flag == null || flag != 1) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ADD_ERROR);
        }

        //插入价格
        ResourcesSpec resourcesSpec = new ResourcesSpec();
        BeanUtils.copyProperties(addResourcesBO,resourcesSpec);
        resourcesSpec.setResourcesId(resources.getId());
        Integer flag1 = resourcesSpecMapper.addPrice(resourcesSpec);
        if (flag1 == null || flag1 != 1) {
            ExceptionUtils.error(ResourcesEnum.RESOURCES_ADD_ERROR);
        }

        //插入图片，默认第一张图片为主图
        for (MultipartFile resourcesImg : resourcesImgs) {
            String fileName = resourcesImg.getOriginalFilename();
            MinIoUtils.uploadFile(minIoClientConfig.getBucketName(),fileName,resourcesImg.getInputStream());
            String imgUrl = minIoClientConfig.getEndpoint() + "/" + minIoClientConfig.getBucketName() + "/" + fileName;

            ResourcesImg resourcesImg1 = new ResourcesImg();
            resourcesImg1.setResourcesId(resources.getId());
            resourcesImg1.setIsMain(0);
            resourcesImg1.setUrl(imgUrl);

            Integer flag2 = resourcesImgMapper.addImg(resourcesImg1);
            if (flag2 == null || flag2 != 1) {
                MinIoUtils.removeFile(minIoClientConfig.getBucketName(),fileName);
                ExceptionUtils.error(ResourcesEnum.RESOURCES_ADD_ERROR);
            }
        }

        //将第一张图片设置为主图
        List<ResourcesImg> resourcesImgList = resourcesImgMapper.getImgByResourcesId(resources.getId());
        ResourcesImg resourcesImg = resourcesImgList.get(0);
        resourcesImg.setIsMain(1);
        resourcesImgMapper.updateResourcesImg(resourcesImg);

        //添加成功后将redis中的缓存清掉
        redisUtils.del("resourcesVOList");

        return Result.success();
    }
}
